package com.pai4j.zwiki.config;

import com.pai4j.common.enums.messagequeue.MessageBroadChannelEnum;
import com.pai4j.zwiki.messagequeue.consumer.redis.ZWikiTaskNotificationRedisListener;
import com.pai4j.zwiki.messagequeue.consumer.redis.ZWikiTaskProgressRedisListener;
import com.pai4j.zwiki.messagequeue.consumer.redis.ZWikiQueueUpdateRedisListener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.util.ErrorHandler;

/**
 * ZWiki Redis配置
 * 配置Redis消息监听器和发布订阅
 *
 * @author pai4j
 * @since 2025-10-14
 */
@Slf4j
@Configuration
public class RedisConfig {

    /**
     * 配置RedisTemplate Bean
     */
    @Bean
    public RedisTemplate<String, Object> zwikiRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        
        // 设置key序列化方式string
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        // 设置value的序列化方式json
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        
        // 设置hash key 和value序列化模式
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        
        // 默认的序列化器
        redisTemplate.setDefaultSerializer(new GenericJackson2JsonRedisSerializer());
        
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    /**
     * 配置Redis消息监听容器
     */
    @Bean
    public RedisMessageListenerContainer zwikiRedisMessageListenerContainer(
            RedisConnectionFactory redisConnectionFactory,
            ZWikiTaskNotificationRedisListener taskNotificationListener,
            ZWikiTaskProgressRedisListener taskProgressListener,
            ZWikiQueueUpdateRedisListener queueUpdateListener) {
        
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        
        // 设置连接工厂
        container.setConnectionFactory(redisConnectionFactory);
        
        // 统一异常处理
        container.setErrorHandler(new ErrorHandler() {
            @Override
            public void handleError(Throwable t) {
                log.error("ZWiki Redis监听器错误: {}", t.getMessage(), t);
            }
        });
        
        // 配置消息监听器
        // 1. 任务通知监听器（任务入队、开始、完成、失败）
        container.addMessageListener(
                taskNotificationListener, 
                new ChannelTopic(MessageBroadChannelEnum.QUEUE_ZWIKI_TASK_NOTIFICATION.getChannel())
        );
        
        // 2. 任务进度监听器（进度更新）
        container.addMessageListener(
                taskProgressListener,
                new ChannelTopic(MessageBroadChannelEnum.QUEUE_ZWIKI_TASK_PROGRESS.getChannel())
        );
        
        // 3. 队列更新监听器（队列位置变化）
        container.addMessageListener(
                queueUpdateListener,
                new ChannelTopic(MessageBroadChannelEnum.QUEUE_ZWIKI_QUEUE_UPDATE.getChannel())
        );
        
        log.info("ZWiki Redis消息监听容器初始化完成，监听频道数: 3");
        
        return container;
    }
}

